// 316. 去除重复字母

function removeDuplicateLetters(s: string): string {
    const BASE = 'a'.charCodeAt(0)
    const cnt = new Array(26).fill(0)
    Array.from(s).forEach(c=>cnt[c.charCodeAt(0)-BASE]++)
    const stack:number[] = []
    const set = new Set<number>()
    let last:number|undefined = 0
    for(let c of s){
        const code = c.charCodeAt(0)
        cnt[code-BASE]--
        if(set.has(code)){
            continue
        }
        while((last=stack.pop())&&last>code&&cnt[last-BASE]>0){
            set.delete(last)
        }
        last!=undefined && stack.push(last)
        stack.push(code)
        set.add(code)
    }
    return stack.reduce((s,cur)=>s+String.fromCharCode(cur),'')
};


/**
    很多这种题都是默认升序或者降序就是最小/大的，一旦有一个违反了，就应该删除它或者其他操作
*/


// 402. 移掉K位数字
function removeKdigits(num: string, k: number): string {
    const stack:number[] = []
    const BASE = '0'.charCodeAt(0)
    let remove = 0
    let last = -1
    for(let c of num){
        const n = c.charCodeAt(0)-BASE
        if(remove<k&&stack.length){
            last = stack.pop()!
            while(remove<k&&last>n){
               remove++
               if(!stack.length||remove==k) break
               last = stack.pop()!
            }
            if(last<=n)stack.push(last)
        }
        stack.push(n)
    }
    while(remove<k){
        remove++
        stack.pop()
    }
    let ans = stack.join('')
    let i 
    for(i=0;i<ans.length&&ans[i]=='0';i++){}
    ans = ans.substring(i+1)
    return ans||'0'
};
